﻿// ===============================================================================
// XCI.NET 西安交通信息WinForm开发框架 2018 版权所有
// ===============================================================================
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using DevExpress.XtraEditors;

namespace XCI.Windows.Controls
{
    /// <summary>
    /// 图片按钮
    /// </summary>
    [System.ComponentModel.DesignerCategory("Code")]
    [DefaultEvent("Click")]
    public class ImageButton : XtraUserControl
    {
        private PictureBox pictureBox;
        //private IContainer components;
        private PictureBox pictureBoxActive;
        private PictureBox pictureBoxNormal;
        private PictureBox pictureBoxMouseDown;
        private Image normalImage;
        private Image grayImage;

        /// <summary>
        /// 设置或获取按钮图片
        /// </summary>
        [Description("设置或获取按钮图片")]
        [Browsable(true)]
        public Image Image
        {
            get
            {
                return this.pictureBoxNormal.Image;
            }
            set
            {
                this.pictureBoxNormal.Image = normalImage = value;
                this.AutoReSize();
            }
        }

        /// <summary>
        /// 设置或获取按钮活动时的图片
        /// </summary>
        [Description("设置或获取按钮活动时的图片")]
        [Browsable(true)]
        public Image ImageActive
        {
            get
            {
                return this.pictureBoxActive.Image;
            }
            set
            {
                this.pictureBoxActive.Image = value;
                this.AutoReSize();
            }
        }

        /// <summary>
        /// 设置或获取按钮按下时的图片
        /// </summary>
        [Description("设置或获取按钮按下时的图片")]
        [Browsable(true)]
        public Image ImageMouseDown
        {
            get
            {
                return this.pictureBoxMouseDown.Image;
            }
            set
            {
                this.pictureBoxMouseDown.Image = value;
                this.AutoReSize();
            }
        }

        /// <summary>
        /// 设置或获取禁用的图片
        /// </summary>
        [Description("设置或获取禁用的图片")]
        [Browsable(true)]
        public Image ImageGray
        {
            get { return grayImage; }
            set
            {
                grayImage = value;
                SetImageGray();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public ImageButton()
        {
            this.InitializeComponent();
            this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
            this.pictureBoxActive.Visible = false;
            this.pictureBoxMouseDown.Visible = false;
            this.pictureBoxNormal.Visible = false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            AutoReSize();
        }

        /// <summary>
        /// 是否启用
        /// </summary>
        public new bool Enabled
        {
            get { return base.Enabled; }
            set
            {
                base.Enabled = value;
                SetImageGray();
            }
        }

        private void AutoReSize()
        {
            this.pictureBoxNormal.Top = 0;
            this.pictureBoxNormal.Left = this.Padding.Left;
            this.pictureBoxActive.Top = 0;
            this.pictureBoxActive.Left = this.Padding.Left;
            this.pictureBoxMouseDown.Top = 0;
            this.pictureBoxMouseDown.Left = this.Padding.Left;
            if (this.pictureBoxNormal.Image != null)
            {
                this.Width = this.pictureBoxNormal.Image.Width + this.Padding.Left + this.Padding.Right;
                this.Height = this.pictureBoxNormal.Image.Height;
                this.pictureBoxNormal.Width = this.pictureBoxNormal.Image.Width;
                this.pictureBoxNormal.Height = this.pictureBoxNormal.Image.Height;
                this.pictureBoxActive.Width = this.pictureBoxNormal.Width;
                this.pictureBoxMouseDown.Width = this.pictureBoxNormal.Width;
            }
            else if (this.pictureBoxActive.Image != null)
            {
                this.Width = this.pictureBoxActive.Image.Width + this.Padding.Left + this.Padding.Right;
                this.Height = this.pictureBoxActive.Image.Height;
                this.pictureBoxActive.Width = this.pictureBoxActive.Image.Width;
                this.pictureBoxActive.Height = this.pictureBoxActive.Image.Height;
                this.pictureBoxNormal.Width = this.pictureBoxActive.Width;
                this.pictureBoxMouseDown.Width = this.pictureBoxActive.Width;
            }
            else if (this.pictureBoxMouseDown.Image != null)
            {
                this.Width = this.pictureBoxMouseDown.Image.Width + this.Padding.Left + this.Padding.Right;
                this.Height = this.pictureBoxMouseDown.Image.Height;
                this.pictureBoxMouseDown.Width = this.pictureBoxMouseDown.Image.Width;
                this.pictureBoxMouseDown.Height = this.pictureBoxMouseDown.Image.Height;
                this.pictureBoxActive.Width = this.pictureBoxMouseDown.Width;
                this.pictureBoxNormal.Width = this.pictureBoxMouseDown.Width;
            }
            this.Invalidate();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="transparencyColor"></param>
        /// <returns></returns>
        protected Region BitmapToRegion(Bitmap bitmap, Color transparencyColor)
        {
            if (bitmap == null)
                throw new ArgumentNullException("bitmap", "图像不能为空!");
            int height = bitmap.Height;
            int width = bitmap.Width;
            GraphicsPath path = new GraphicsPath();
            for (int y = 0; y < height; ++y)
            {
                for (int x1 = 0; x1 < width; ++x1)
                {
                    if (!(bitmap.GetPixel(x1, y) == transparencyColor))
                    {
                        int x2 = x1;
                        while (x1 < width && bitmap.GetPixel(x1, y) != transparencyColor)
                            ++x1;
                        path.AddRectangle(new Rectangle(x2, y, x1 - x2, 1));
                    }
                }
            }
            Region region = new Region(path);
            path.Dispose();
            return region;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaddingChanged(EventArgs e)
        {
            this.AutoReSize();
        }

        private void pictureBoxNormal_MouseEnter(object sender, EventArgs e)
        {
            this.pictureBoxActive.BringToFront();
        }

        private void pictureBoxActive_MouseLeave(object sender, EventArgs e)
        {
            this.pictureBoxNormal.BringToFront();
        }

        private void pictureBoxActive_MouseClick(object sender, MouseEventArgs e)
        {
        }

        private void pictureBoxActive_MouseDown(object sender, MouseEventArgs e)
        {
            this.pictureBoxMouseDown.BringToFront();
            if (this.ContextMenuStrip == null)
                return;
            this.ContextMenuStrip.Show(this, new Point(0, this.Height - 1));
        }

        private void pictureBoxMouseDown_MouseLeave(object sender, EventArgs e)
        {
            this.pictureBoxNormal.BringToFront();
        }

        private void pictureBoxMouseDown_Click(object sender, EventArgs e)
        {
        }

        private void pictureBoxMouseDown_MouseUp(object sender, MouseEventArgs e)
        {
        }

        private void pictureBoxActive_MouseUp(object sender, MouseEventArgs e)
        {
            this.OnClick(e);
        }

        /// <summary>
        /// 设置样式
        /// </summary>
        /// <param name="controlStyles"></param>
        /// <param name="value"></param>
        public new void SetStyle(ControlStyles controlStyles, bool value)
        {
            base.SetStyle(controlStyles, value);
        }

        internal void SetImageGray()
        {
            if (ImageGray == null) return;
            if (this.Enabled)
            {
                this.pictureBoxNormal.Image = normalImage;
            }
            else
            {
                this.pictureBoxNormal.Image = grayImage;
            }
            this.pictureBox = this.pictureBoxNormal;
            this.Invalidate();
        }

        internal void SetMouseEnter()
        {
            if (this.pictureBox == this.pictureBoxActive)
                return;
            this.pictureBox = this.pictureBoxActive;
            this.Invalidate();
        }

        internal void SetMouseLeave()
        {
            if (this.pictureBox == this.pictureBoxNormal)
                return;
            this.pictureBox = this.pictureBoxNormal;
            this.Invalidate();
        }
        
        private void EasyImageButton_Paint(object sender, PaintEventArgs e)
        {
            if (this.pictureBox == null)
                this.pictureBox = this.pictureBoxNormal;
            if (this.pictureBox == null || this.pictureBox.Image == null)
                return;
            e.Graphics.DrawImage(this.pictureBox.Image, new Rectangle(0, 0, this.pictureBox.Width, this.pictureBox.Height));
        }

        private void EasyImageButton_MouseDown(object sender, MouseEventArgs e)
        {
            if (this.ContextMenuStrip != null)
            {
                if (this.ContextMenuStrip.Visible)
                    this.ContextMenuStrip.Visible = false;
                else
                    this.ContextMenuStrip.Show(this, new Point(0, this.Height - 1));
            }
            if (this.pictureBox == this.pictureBoxNormal)
                return;
            this.pictureBox = this.pictureBoxNormal;
            this.Invalidate();
        }

        private void EasyImageButton_MouseEnter(object sender, EventArgs e)
        {
            this.SetMouseEnter();
        }

        private void EasyImageButton_MouseLeave(object sender, EventArgs e)
        {
            this.SetMouseLeave();
        }

        //protected override void Dispose(bool disposing)
        //{
        //    //if (disposing && this.components != null)
        //    //    this.components.Dispose();
        //    base.Dispose(disposing);
        //}

        private void InitializeComponent()
        {
            this.pictureBoxNormal = new PictureBox();
            this.pictureBoxActive = new PictureBox();
            this.pictureBoxMouseDown = new PictureBox();
            ((ISupportInitialize)this.pictureBoxNormal).BeginInit();
            ((ISupportInitialize)this.pictureBoxActive).BeginInit();
            ((ISupportInitialize)this.pictureBoxMouseDown).BeginInit();
            this.SuspendLayout();
            this.pictureBoxNormal.BackColor = Color.Transparent;
            this.pictureBoxNormal.Location = new Point(0, 0);
            this.pictureBoxNormal.Name = "pictureBoxNormal";
            this.pictureBoxNormal.Size = new Size(67, 50);
            this.pictureBoxNormal.TabIndex = 0;
            this.pictureBoxNormal.TabStop = false;
            this.pictureBoxNormal.MouseEnter += new EventHandler(this.pictureBoxNormal_MouseEnter);
            this.pictureBoxActive.BackColor = Color.Transparent;
            this.pictureBoxActive.Location = new Point(0, 0);
            this.pictureBoxActive.Name = "pictureBoxActive";
            this.pictureBoxActive.Size = new Size(67, 50);
            this.pictureBoxActive.SizeMode = PictureBoxSizeMode.AutoSize;
            this.pictureBoxActive.TabIndex = 0;
            this.pictureBoxActive.TabStop = false;
            this.pictureBoxActive.MouseLeave += new EventHandler(this.pictureBoxActive_MouseLeave);
            this.pictureBoxActive.MouseClick += new MouseEventHandler(this.pictureBoxActive_MouseClick);
            this.pictureBoxActive.MouseDown += new MouseEventHandler(this.pictureBoxActive_MouseDown);
            this.pictureBoxActive.MouseUp += new MouseEventHandler(this.pictureBoxActive_MouseUp);
            this.pictureBoxMouseDown.BackColor = Color.Transparent;
            this.pictureBoxMouseDown.Location = new Point(0, 0);
            this.pictureBoxMouseDown.Name = "pictureBoxMouseDown";
            this.pictureBoxMouseDown.Size = new Size(67, 50);
            this.pictureBoxMouseDown.TabIndex = 0;
            this.pictureBoxMouseDown.TabStop = false;
            this.pictureBoxMouseDown.MouseLeave += new EventHandler(this.pictureBoxMouseDown_MouseLeave);
            this.pictureBoxMouseDown.Click += new EventHandler(this.pictureBoxMouseDown_Click);
            this.pictureBoxMouseDown.MouseUp += new MouseEventHandler(this.pictureBoxMouseDown_MouseUp);
            this.AutoScaleMode = AutoScaleMode.None;
            this.Controls.Add(this.pictureBoxNormal);
            this.Controls.Add(this.pictureBoxActive);
            this.Controls.Add(this.pictureBoxMouseDown);
            this.Name = "ImageButton";
            this.Size = new Size(122, 73);
            this.MouseLeave += new EventHandler(this.EasyImageButton_MouseLeave);
            this.Paint += new PaintEventHandler(this.EasyImageButton_Paint);
            this.MouseDown += new MouseEventHandler(this.EasyImageButton_MouseDown);
            this.MouseEnter += new EventHandler(this.EasyImageButton_MouseEnter);
            ((ISupportInitialize)this.pictureBoxNormal).EndInit();
            ((ISupportInitialize)this.pictureBoxActive).EndInit();
            ((ISupportInitialize)this.pictureBoxMouseDown).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();
        }
    }
}